大家好~
今天是最後一天了,
來將這幾天所學結合成一個小作品吧!
功能部分就是當使用者跟 LINEBot 說什麼時候要開會,
LINEBot 會回應一個 Google Meet 的會議連結。
功能滿簡單的,
所以我決定用 Dialogflow 這個架構。
LINEBot Channel 申請可以參考 Day12,
Dialogflow 與 LINEBot Channel 連動設定可以參考 Day26,
Dialogflow Intent 的訓練也可以參考 Day26,
Google Calendar 會用 Oauth 的憑證,
可以參考 Day25。
底下就是程式的實作啦~
Route::post('/dialogflow', [DialogflowController::class, 'intent']);
開個 Webhook 給 Dialogflow。
use Illuminate\Http\Request;
use Google\Client;
use Google\Service\Calendar;
use Google\Service\Calendar\Event;
use Google\Service\Calendar\EventDateTime;
use Google\Service\Calendar\ConferenceData;
use Google\Service\Calendar\ConferenceSolutionKey;
use Google\Service\Calendar\CreateConferenceRequest;
class GoogleMeetController extends Controller
{
protected $client;
protected $calendar;
protected $calendarId;
public function __construct()
{
$this->client = new Client();
$this->client->setAuthConfig(env('OAUTH_CLIENT_CREDENTIALS_PATH'));
$this->client->addScope(Calendar::CALENDAR_EVENTS);
$tokenPath = env('OAUTH_TOKEN_JSON_PATH');
$accessToken = json_decode(file_get_contents($tokenPath), true);
$this->client->setAccessToken($accessToken);
$this->calendar = new Calendar($this->client);
$this->calendarId = env('GOOGLE_CALENDAR_ID');
}
public function create($request)
{
$calendarEvent = new Event();
$conferenceSolutionKey = new ConferenceSolutionKey();
$conferenceSolutionKey->setType('hangoutsMeet');
$createConferenceRequest = new CreateConferenceRequest();
$createConferenceRequest->setRequestId(md5('ironman2021' . time()));
$createConferenceRequest->setConferenceSolutionKey($conferenceSolutionKey);
$conferenceData = new ConferenceData();
$conferenceData->setCreateRequest($createConferenceRequest);
$calendarEvent->setConferenceData($conferenceData);
$calendarEvent->setSummary($request['summary']);
$startTime = new EventDateTime();
$startTime->setDateTime($request['startTime']);
$calendarEvent->setStart($startTime);
$endTime = new EventDateTime();
$endTime->setDateTime($request['endTime']);
$calendarEvent->setEnd($endTime);
$response = $this->calendar->events->insert(
$this->calendarId,
$calendarEvent,
[
'conferenceDataVersion' => 1
]
);
return $response->getHangoutLink();
}
}
GoogleMeetController
會在指定時間建立一個 Google Calendar Event,
然後回傳 Google Meet 連結。
env 的設定也是和 Day25 一樣喔~
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\GoogleMeetController;
class DialogflowController extends Controller
{
public function intent(Request $request)
{
$queryText = $request->queryResult['queryText'];
$datetime = $request->queryResult['outputContexts'][0]['parameters']['date-time'];
$meetData['summary'] = "開會";
switch ($datetime) {
case is_string($datetime):
$meetData['startTime'] = $datetime;
$meetData['endTime'] = Carbon::parse($datetime)->addHour()->toRfc3339String();
break;
case is_array($datetime):
if (isset($datetime['date_time'])) {
$startTime = $datetime['date_time'];
$meetData['startTime'] = $startTime;
$meetData['endTime'] = Carbon::parse($startTime)->addHour()->toRfc3339String();
} elseif (isset($datetime['startDateTime'])) {
$startTime = $datetime['startDateTime'];
$endTime = $datetime['endDateTime'];
$meetData['startTime'] = $startTime;
$meetData['endTime'] = $endTime;
} else {
$startTime = $datetime['startTime'];
$endTime = $datetime['endTime'];
$meetData['startTime'] = $startTime;
$meetData['endTime'] = $endTime;
}
break;
default:
return response('400', Response::HTTP_BAD_REQUEST);
}
$googleMeetController = new GoogleMeetController;
$url = $googleMeetController->create($meetData);
$jsonResponse = [
"fulfillmentMessages" => [
[
"text" => [
"text" => [
$url
]
]
]
]
];
return $jsonResponse;
}
}
DialogflowController
會將 Google Meet 連結傳給 Dialogflow。
這樣就差不多完成啦~
以下開始成果預覽!
功能測試成功!
以上程式碼僅僅只是可動而已,
還有許多的不足,
例外處理以及一些安全上的問題都還沒完善,
像是 Dialogflow 發送的 Request 沒在 Headers 加入驗證相關的訊息,DialogflowController
也沒有對 Request 做驗證。
之後還有更多要加強的地方,
這只是個起點。
感謝30天來收看的你~
若文章有任何問題,
還請不吝賜教!
也歡迎一起討論~
謝謝大家!